﻿using EasyNetQ;

namespace Magic.Rmq;

public class RmqProvider
{

    public static void Enqueue<T>(T messageDto, string routeKey, PriorityLevel priorityLevel = PriorityLevel.Lower) where T : class
    {
        if (messageDto == null)
            return;
        RmqService.Enqueue(messageDto, routeKey, priorityLevel);
    }

    /// <summary>
    /// 推送
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="messageDto"></param>
    /// <param name="routeKey"></param>
    /// <param name="priorityLevel"></param>
    /// <returns></returns>
    public static Task EnqueueAsync<T>(T messageDto, string routeKey, PriorityLevel priorityLevel = PriorityLevel.Lower) where T : class
    {
        return RmqService.EnqueueAsync(messageDto, routeKey, priorityLevel);
    }

    public static Task<int> GetQueueCountAsync(string queueName)
    {
        return RmqService.GetQueueCountAsync(queueName);
    }

    public static int GetQueueCount(string queueName)
    {
        return RmqService.GetQueueCount(queueName);
    }

    /// <summary>
    /// 获取一条消息(循环阻塞，直到获取到消息为止)
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="queueName"></param>
    /// <returns></returns>
    public static Task<T> GetOneMessageAsync<T>(string queueName)
    {
        return RmqService.GetOneMessageLoopAsync<T>(queueName);
    }

    /// <summary>
    /// 循环阻塞获取消息，直到获取到count条数据或timeout到期为止（默认无限期等待）
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="queueName"></param>
    /// <param name="count"></param>
    /// <param name="timeout"></param>
    /// <returns></returns>
    public static Task<List<T>> GetBatchMessageAsync<T>(string queueName, int count, TimeSpan? timeout = null)
    {
        return RmqService.GetBatchMessageLoopAsync<T>(queueName, count, timeout);
    }

    /// <summary>
    /// 添加队列
    /// </summary>
    /// <param name="queueName">队列名称</param>
    /// <param name="deadName">死信队列名称</param>
    /// <param name="timeSpan"></param>
    /// <param name="isDelay"></param>
    /// <returns></returns>
    public static async Task AddQueue(string queueName, string deadName = null, TimeSpan? timeSpan = null, bool isDelay = false)
    {
        var _bus = RmqService.GetAdvancedClient(RmqOptions.ConnectionString);

        var exchange = await _bus.ExchangeDeclareAsync("Gate", config =>
        {
            config.AsDurable(true)
            .WithType("topic")
            .AsAutoDelete(false)
            ;
        });
        var queue = await _bus.QueueDeclareAsync(queueName, config =>
        {
            config.AsDurable(true)
            .AsAutoDelete(false)
            .WithQueueType("classic")
            .WithMaxPriority(10);

            if (!string.IsNullOrWhiteSpace(deadName))
            {
                // 配置死信路由
                config.WithDeadLetterExchange(exchange)
                      .WithDeadLetterRoutingKey(deadName);
                if (isDelay)
                {
                    config.WithMessageTtl(timeSpan.Value);
                }
            }

        });
        _bus.Bind(exchange, queue, queue.Name);

        if (isDelay == false && !string.IsNullOrWhiteSpace(deadName))
        {
            var deadQueue = await _bus.QueueDeclareAsync(deadName, config =>
            {
                config.AsDurable(true)
                .AsAutoDelete(false)
                .WithQueueType("classic")
                .WithMaxPriority(10);

                if (timeSpan.HasValue)
                {
                    // 存在重试，这配置死信到 队列的路由
                    config.WithDeadLetterExchange(exchange)
                   .WithDeadLetterRoutingKey(queueName);
                    config.WithMessageTtl(timeSpan.Value);
                }

            });
            _bus.Bind(exchange, deadQueue, deadQueue.Name);
        }


    }
}
